home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / xlib06p1.zip / XLINE.CPP < prev    next >
C/C++ Source or Header  |  1995-03-15  |  7KB  |  298 lines

  1. #include "xinternl.h"
  2. #include <conio.h>
  3. #include <mem.h>
  4. /*==================================================================
  5. XLINE.CPP contains the code for simple bresenham lines in mode x.
  6. Modified from w_modex.zip code, author unknown.
  7.  
  8. Modified March 1995 by Victor B. Putz.
  9. ===================================================================*/
  10.  
  11. WORD abPlaneMask[] = {
  12.   0x0102,
  13.   0x0202,
  14.   0x0402,
  15.   0x0802
  16. };
  17.  
  18. extern unsigned char abLeftClipPlaneMask[];
  19. extern unsigned char abRightClipPlaneMask[];
  20.  
  21. extern BYTE * pbVGABuffer;
  22. extern int ScrnLogicalByteWidth;
  23.  
  24.  
  25.  
  26. void _HorizontalLine(
  27.     xPageHandle_t wOffset,
  28.     xScreenCoord_t iLeftX,
  29.     xScreenCoord_t iY,
  30.     int iLength,
  31.     xColor_t iColor
  32. )
  33. {
  34.   if ( iLength < 0 ) {
  35.     return;
  36.   }
  37.   BYTE * pb = pbVGABuffer + wOffset + ( ScrnLogicalByteWidth * iY ) + iLeftX / 4;
  38.   int iTemp;
  39.   //do the left part of the line
  40.   if ( iTemp = ( iLeftX & 3 ) ) {
  41.     outp( SC_INDEX, 0x02 );
  42.     outp( SC_INDEX + 1, abLeftClipPlaneMask[ iTemp ] );
  43.     *pb++ = ( BYTE )iColor;
  44.     iLength -= ( 4 - iTemp );
  45.   }
  46.   if ( iLength < 0 ) {
  47.     return;
  48.   }
  49.   //the middle
  50.   if ( iTemp = ( iLength >> 2 ) ) {
  51.     outpw( SC_INDEX, 0x0f02 );
  52.     iLength &= 3;
  53.     memset( pb, iColor, iTemp );
  54.     pb += iTemp;
  55.   }
  56.   //then the right part
  57.   if ( iLength ) {
  58.     outp( SC_INDEX, 0x02 );
  59.     outp( SC_INDEX + 1, abRightClipPlaneMask[ iLength ] );
  60.     *pb = ( BYTE )iColor;
  61.   }
  62. }
  63.  
  64.  
  65. void _VerticalLine(
  66.     xPageHandle_t wOffset,
  67.   xScreenCoord_t iX,
  68.   xScreenCoord_t iTopY,
  69.   int iLength,
  70.   xColor_t iColor
  71. )
  72. {
  73.   int iTemp = ( iX & 3 );
  74.  
  75.   outpw(SC_INDEX, abPlaneMask[iTemp]);
  76.  
  77.   BYTE * pbDest = pbVGABuffer + wOffset + ( iTopY * ScrnLogicalByteWidth ) + (iX / 4);
  78.  
  79.   while (iLength--) {
  80.     *pbDest = ( BYTE )iColor;
  81.     pbDest += ScrnLogicalByteWidth;
  82.   }
  83. }
  84.  
  85.  
  86. void internal_xmajor(
  87.     BYTE * pbDest,
  88.     int iLength,     //was short
  89.     int iYSkip,        //was short
  90.   unsigned long ErrorAcc,
  91.     unsigned long ErrorAdj,
  92.     BYTE bColor
  93. )
  94. {
  95.   if (iLength) {
  96.     iLength--;
  97.     while (iLength--) {
  98.       *pbDest++ = bColor;
  99.       ErrorAcc += ErrorAdj;
  100.  
  101.       if (ErrorAcc & ~0xFFFFL) {
  102.         ErrorAcc &= 0xFFFFL;
  103.         pbDest += iYSkip;
  104.       }
  105.     }
  106.     *pbDest = bColor;
  107.   }
  108. }
  109.  
  110. void internal_middle(
  111.     BYTE *pbDest,
  112.     int iLength,    //was short
  113.     int iYSkip,        //was short
  114.   unsigned long ErrorAcc,
  115.     unsigned long ErrorAdj,
  116.     BYTE bColor
  117. )
  118. {
  119.   if (iLength) {
  120.     iLength--;
  121.     while (iLength--) {
  122.       *pbDest++ = bColor;
  123.       ErrorAcc += ErrorAdj;
  124.       pbDest += (iYSkip * (ErrorAcc >> 16));
  125.       ErrorAcc &= 0xFFFFL;
  126.     }
  127.     *pbDest = bColor;
  128.   }
  129. }
  130.  
  131.  
  132. void internal_ymajor(
  133.     BYTE *pbDest,
  134.     int iLength,  //was short
  135.     int iYSkip,        //was short
  136.   unsigned long ErrorAcc,
  137.     unsigned long ErrorAdj,
  138.     BYTE bColor
  139. )
  140. {
  141.   unsigned long TinyAdj;
  142.   int i;//was short
  143.  
  144.   if (iLength) {
  145.     TinyAdj = (ErrorAdj >> 2);
  146.     ErrorAdj -= TinyAdj;
  147.  
  148.     iLength--;
  149.     while (iLength--) {
  150.       ErrorAcc += TinyAdj;
  151.       i = (ErrorAcc >> 16);
  152.       ErrorAcc &= 0xFFFFL;
  153.  
  154.       while (i--) {
  155.         *pbDest = bColor;
  156.         pbDest += iYSkip;
  157.       }
  158.  
  159.       ErrorAcc += ErrorAdj;
  160.       pbDest += (iYSkip * (ErrorAcc >> 16)) + 1;
  161.       ErrorAcc &= 0xFFFFL;
  162.     }
  163.     ErrorAcc += TinyAdj;
  164.     i = (ErrorAcc >> 16);
  165.     while (i--) {
  166.       *pbDest = bColor;
  167.       pbDest += iYSkip;
  168.     }
  169.   }
  170. }
  171.  
  172.  
  173.  
  174. void x_line(     /* Draw a line, what else */
  175.   xScreenCoord_t x1,
  176.   xScreenCoord_t y1,
  177.   xScreenCoord_t x2,
  178.   xScreenCoord_t y2,
  179.   xColor_t color,
  180.   xPageHandle_t PageBase
  181. )
  182. {
  183.  
  184.   unsigned long ErrorAcc, ErrorAdj, TinyAdj;
  185.   int i, DeltaX, DeltaY, yskip;    //was short
  186.   int len[4];    //was short
  187.   BYTE * pbDest;
  188.   int iTemp;
  189.  
  190.   // Mode X 4-way folded Bresenham line function - by David Boeren
  191.   //modified to fit XLIB by Victor Putz
  192.  
  193.   // Make sure the line runs left to right by swapping ends if necessary
  194.   if (x1 > x2) {
  195.     iTemp = x1; x1 = x2; x2 = iTemp;
  196.     iTemp = y1; y1 = y2; y2 = iTemp;
  197.   }
  198.  
  199.   DeltaX = (x2 - x1);
  200.   DeltaY = (y2 - y1);
  201.  
  202.   if (DeltaY >= 0) {
  203.     yskip = ScrnLogicalByteWidth;
  204.   } else {
  205.     DeltaY = -DeltaY;  // Make DeltaY positive
  206.     yskip = -ScrnLogicalByteWidth;
  207.   }
  208.  
  209.   if (DeltaX == 0) {
  210.       // Vertical Line (and one pixel lines)
  211.       if (yskip > 0) {
  212.           _VerticalLine(PageBase, x1, y1, (DeltaY + 1), color);
  213.       } else {
  214.           _VerticalLine(PageBase, x1, y2, (DeltaY + 1), color);
  215.       }
  216.       return;
  217.   }
  218.  
  219.   if (DeltaY == 0) {
  220.       // Horizontal Line
  221.       _HorizontalLine(PageBase, x1, y1, (DeltaX + 1), color);
  222.       return;
  223.   }
  224.  
  225.   pbDest = pbVGABuffer + PageBase + ( y1 * ScrnLogicalByteWidth ) + (x1 / 4);
  226.   ErrorAcc = 0x8000;
  227.  
  228.   // Length of sub-line in each plane
  229.   iTemp = (x1 & 3);
  230.   i = DeltaX + iTemp;
  231.   len[0] = ((i--) >> 2);
  232.   len[1] = ((i--) >> 2);
  233.   len[2] = ((i--) >> 2);
  234.   len[3] = (i >> 2) + 1;
  235.  
  236.   for (i=iTemp; i < 3; i++) {
  237.       len[i]++;
  238.   }
  239.  
  240.   if ((DeltaX >> 2) >= DeltaY) {
  241.     // X-Major line (0.00 < slope <= 0.25)
  242.     ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));
  243.     TinyAdj = (ErrorAdj >> 2);
  244.     while (i--) {
  245.       outpw(SC_INDEX, abPlaneMask[iTemp]);
  246.       internal_xmajor(pbDest, len[iTemp++], yskip, ErrorAcc, ErrorAdj, color);
  247.       if (iTemp == 4) {
  248.         iTemp = 0;
  249.         pbDest++;
  250.       }
  251.       ErrorAcc += TinyAdj;
  252.       if (ErrorAcc & ~0xFFFFL) {
  253.         ErrorAcc &= 0xFFFFL;
  254.         pbDest += yskip;
  255.       }
  256.     }
  257.     outpw(SC_INDEX, abPlaneMask[iTemp]);
  258.     internal_xmajor(pbDest, len[iTemp], yskip, ErrorAcc, ErrorAdj, color);
  259.   } else if (DeltaX >= DeltaY) {
  260.     // Middle line (0.25 < slope <= 1.00)
  261.     ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));
  262.     TinyAdj = (ErrorAdj >> 2);
  263.     while (i--) {
  264.       outpw(SC_INDEX, abPlaneMask[iTemp]);
  265.       internal_middle(pbDest, len[iTemp++], yskip, ErrorAcc, ErrorAdj, color);
  266.       if (iTemp == 4) {
  267.         iTemp = 0;
  268.         pbDest++;
  269.       }
  270.       ErrorAcc += TinyAdj;
  271.       if (ErrorAcc & ~0xFFFFL) {
  272.         pbDest += yskip;
  273.         ErrorAcc &= 0xFFFFL;
  274.       }
  275.     }
  276.     outpw(SC_INDEX, abPlaneMask[iTemp]);
  277.     internal_middle(pbDest, len[iTemp], yskip, ErrorAcc, ErrorAdj, color);
  278.   } else {
  279.     // Y-Major line (slope > 1)
  280.     ErrorAdj = ((((unsigned long)(DeltaY+1) << 18) /
  281.       (unsigned long)(DeltaX+1)));
  282.     TinyAdj = (ErrorAdj >> 2);
  283.     while (i--) {
  284.       outpw(SC_INDEX, abPlaneMask[iTemp]);
  285.       internal_ymajor(pbDest, len[iTemp++], yskip, ErrorAcc, ErrorAdj, color);
  286.       if (iTemp == 4) {
  287.         iTemp = 0;
  288.         pbDest++;
  289.       }
  290.       ErrorAcc += TinyAdj;
  291.       pbDest += (yskip * (ErrorAcc >> 16));
  292.       ErrorAcc &= 0xFFFFL;
  293.     }
  294.     outpw(SC_INDEX, abPlaneMask[iTemp]);
  295.     internal_ymajor(pbDest, len[iTemp], yskip, ErrorAcc, ErrorAdj, color);
  296.   }
  297. }
  298.